
;;Fundamental tasks
(defun make-task (task time date)
  (list :task task :length time :date date ) )

;;tasklist Global Variable
(defvar *tasklist* nil)

;html tag for a checkbox <input type="checkbox" name="completed" value="on">
(defvar *checkboxtag* " <input type= ")
(setq *checkboxtag* " <input type=\"checkbox\" name=\"completed\" value=\"on\"> ")

(defun add-task (task) (push task *tasklist*))

;output the database in an html format
(defun dump-db ()
  (format t "~a,~30t~a,~40t~a~%" "Task" "length" "Date")
  (dolist (task *tasklist*)
   (or (format t "~{~*~a,~30t~*~a,~40t~*~a ~}~%" task) 0)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load tasks from file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun save-tasklist (filename)
  (with-open-file (out filename
                   :direction :output
                   :if-exists :supersede)
    (with-standard-io-syntax
      (print *tasklist* out))))

(defun load-tasklist (filename)
  (with-open-file (in filename)
    (with-standard-io-syntax
      (setf *tasklist* (read in)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Controls to prompt for task entry
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defun prompt-read (prompt)
  (format *query-io* "~a: " prompt)
  (force-output *query-io*)
  (read-line *query-io*))

(defun prompt-for-task ()
  (make-task
   (prompt-read "Task Description")
   (prompt-read "Task Length")
   (prompt-read "Date completed by")
   ))


(defun create-tasklist ()
  (loop (add-task (prompt-for-task))
      (if (not (y-or-n-p "Another? [y/n]: ")) (return))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;SQL style query controls
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;USAGE EXAMPLE => (select (where :item "koobla kahn"))
(defun where (&key task time date )
  #'(lambda (taskselect)
      (and
       (if task   (equal (getf taskselect :task) task)  t)
       (if time   (equal (getf taskselect :time) time) t)
       (if date   (equal (getf taskselect :date) date) t))))

(defun select (selector-fn)
  (remove-if-not selector-fn *tasklist*))

;USAGE EXAMPLE => (update (where :task "koobla kahn") :time 11 minb)
(defun update (selector-fn &key task time date)
  (setf *tasklist*
        (mapcar
         #'(lambda (row)
             (when (funcall selector-fn row)
               (if title    (setf (getf row :task) task))
               (if artist   (setf (getf row :time) time))
               (if rating   (setf (getf row :date) date)))
             row) *tasklist*)))

(defun get-priority(task1 task2)
  (format t "Is ~a higher priority than ~a ? ~%" (nth 1 task1) (nth 1 task2))
   (if(not(y-or-n-p "? [y/n]: ")) (values nil) (values t)))


(defun swap_elements(a b);;swaps two entries in *tasklist*
  (setf temp (nth a *tasklist*))
  (setf (nth a *tasklist*) (nth b *tasklist*))
  (setf (nth b *tasklist*) temp))
 


(defun battle ()
  (setf temp nil)
  (do ((i 0 (+ i 1))) 
      ((= i (length *tasklist*)))
    (do ((j (+ i 1) (+ j 1)))
	((eq (nth (- j 1) *tasklist*) nil))
      (if (not (get-priority (nth i *tasklist*) (nth j *tasklist*))) 
	  (funcall #'(lambda () 
		       (nreverse temp)
		       (pushnew (nth i *tasklist*) temp)
		       (nreverse temp)))
	  (pushnew (nth i *tasklist*) temp))))
  (setf *tasklist* temp))


      
	  